/*
 * Copyright 2016-present the IoT DC3 original author or authors.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package io.github.pnoker.common.utils;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import io.github.pnoker.common.constant.common.DefaultConstant;
import io.github.pnoker.common.constant.common.ExceptionConstant;
import io.github.pnoker.common.constant.common.TimeConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.sql.Types;

/**
 * Mybatis 工具类集合
 *
 * @author pnoker
 * @version 2025.9.0
 * @since 2022.1.0
 */
@Slf4j
public class MybatisUtil {

    private MybatisUtil() {
        throw new IllegalStateException(ExceptionConstant.UTILITY_CLASS);
    }

    /**
     * 默认的代码生成器
     * <p>
     * 数据库相关的连接参数会被环境变量覆盖
     *
     * @param defaultHost     默认的数据库主机
     * @param defaultPort     默认的数据库端口
     * @param defaultDb       默认的数据库名称
     * @param defaultSchema   默认的数据库 Schema
     * @param defaultUsername 默认的数据库用户名
     * @param defaultPassword 默认的数据库密码
     * @return FastAutoGenerator
     */
    public static FastAutoGenerator defaultGenerator(String defaultHost, String defaultPort, String defaultDb, String defaultSchema, String defaultUsername, String defaultPassword) {
        String host = System.getenv("POSTGRES_HOST");
        if (StringUtils.isEmpty(host)) {
            host = defaultHost;
        }
        String port = System.getenv("POSTGRES_PORT");
        if (StringUtils.isEmpty(port)) {
            port = defaultPort;
        }
        String db = System.getenv("POSTGRES_DB");
        if (StringUtils.isEmpty(db)) {
            db = defaultDb;
        }
        String schema = System.getenv("POSTGRES_SCHEMA");
        if (StringUtils.isEmpty(schema)) {
            schema = defaultSchema;
        }
        String username = System.getenv("POSTGRES_USERNAME");
        if (StringUtils.isEmpty(username)) {
            username = defaultUsername;
        }
        String password = System.getenv("POSTGRES_PASSWORD");
        if (StringUtils.isEmpty(password)) {
            password = defaultPassword;
        }

        return FastAutoGenerator.create(
                String.format("jdbc:postgresql://%s:%s/%s?currentSchema=%s&useSSL=false", host, port, db, schema),
                username,
                password
        );
    }

    /**
     * 默认的全局配置
     *
     * @param builder {@link GlobalConfig.Builder}
     * @param path    生成文件的根目录
     */
    public static void defaultGlobalConfig(GlobalConfig.Builder builder, String path) {
        builder.outputDir(path + "/java")
                .author(DefaultConstant.USER_NAME)
                .commentDate(TimeConstant.DAY_DATE_FORMAT1)
                .disableOpenDir();
    }

    /**
     * 默认的数据源配置
     *
     * @param builder {@link DataSourceConfig.Builder}
     */
    public static void defaultDataSourceConfig(DataSourceConfig.Builder builder) {
        builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
            int typeCode = metaInfo.getJdbcType().TYPE_CODE;
            if (typeCode == Types.SMALLINT) {
                return DbColumnType.BYTE;
            }
            return typeRegistry.getColumnType(metaInfo);
        });
    }

    /**
     * 默认的生成策略配置
     *
     * @param builder {@link StrategyConfig.Builder}
     */
    public static void defaultStrategyConfig(StrategyConfig.Builder builder) {
        builder.addTablePrefix("dc3_")
                .entityBuilder()
                .idType(IdType.ASSIGN_ID)
                .enableLombok()
                .formatFileName("%sDO")
                .enableTableFieldAnnotation()
                .enableRemoveIsPrefix()
                .enableFileOverride()
                .logicDeleteColumnName("deleted")
                .controllerBuilder()
                .disable()
                .serviceBuilder()
                .formatServiceFileName("%sManager")
                .formatServiceImplFileName("%sManagerImpl")
                .enableFileOverride()
                .mapperBuilder()
                .enableFileOverride();
    }

}
